package com.moonshineproject.plugin.actionscript.as3parser.swcparser
{
	import __AS3__.vec.Vector;
	
	import com.moonshineproject.GlobalEventDispatcher;
	import com.moonshineproject.plugin.actionscript.as3parser.vo.PackageVO;
	import com.moonshineproject.plugin.actionscript.as3project.vo.AS3ProjectVO;
	import com.moonshineproject.plugin.actionscript.mxmlc.MXMLCPlugin;
	import com.moonshineproject.plugin.console.ConsoleOutputter;
	import com.moonshineproject.plugin.settings.event.RequestSettingEvent;
	
	import deng.utils.ChecksumUtil;
	
	import flash.filesystem.File;
	import flash.utils.ByteArray;
	
	public class SWCManager extends ConsoleOutputter
	{	
		override public function get name():String { return "AS3 Autocompletion"; }
		
		public function getContents(swc:File):PackageVO
		{
			var serializer:SWCDataSerializer = new SWCDataSerializer();
			
			var cache:File = getCachedFile(swc);
			if (cache)
			{
				// Get cached version
				return serializer.deserialize(cache);	
			}
			else
			{
				// Parse file
				var parser:SWCParser = new SWCParser();
				var pkg:PackageVO = parser.parseSWC(swc);
				
				// Save cached version
				serializer.serialize(encodeFilename(swc), pkg);
				
				return pkg;
			}
		}
		
		public function getCompilerSWCS(project:AS3ProjectVO):Vector.<File>
		{
			var libs:Vector.<File> = new Vector.<File>();
			
			var sdk:File = project.buildOptions.customSDK;
			if (!sdk)
			{
				var event:RequestSettingEvent = new RequestSettingEvent(MXMLCPlugin, 'defaultFlexSDK');
				GlobalEventDispatcher.getInstance().dispatchEvent(
					event
				);
				
				sdk = new File(event.value as String);
				
				if (!event.value || !sdk || !sdk.exists)
				{ 
					print("No Flex SDK found, either set one for the project or for the MXMLC Plugin. And restart.");
					return libs;
				} 
			}
			
			var libDir:File = sdk.resolvePath("frameworks" + File.separator + "libs");
			if (!libDir || !libDir.exists) return libs;
			var version:String = project.swfOutput.swfVersion.toString();
			
			var dotCount:int = version.split(".").length-1;
			if (dotCount == 0) {
				version += ".0";
			}
			
			var playerSWC:File;
			if (project.air)
			{
				playerSWC = libDir.resolvePath("air" + File.separator + "airglobal.swc");
			}
			else
			{
				libDir = libDir.resolvePath("player" + File.separator + version);
				playerSWC = libDir.resolvePath("playerglobal.swc");
			}
			
			if (playerSWC.exists)
				libs.push(playerSWC);
			
			return libs;
		}
		
		protected function getCachedFile(swc:File):File
		{
			var storage:File = SWCDataSerializer.getCacheDir();
			
			var name:String = encodeFilename(swc);
			var listing:Array = storage.getDirectoryListing();
			for each (var cachedSWC:File in listing)
			{
				if (cachedSWC.name == name)
				{
					return cachedSWC;
				}
			}
			
			return null;
		}
		
		protected function encodeFilename(file:File):String
		{
			// TODO: Figure out what's CORRECT to use in this situation.
			var ba:ByteArray = new ByteArray();
			ba.writeUTF(file.nativePath);
			
			var checksum:uint = ChecksumUtil.Adler32(ba);
			return file.name + "." + checksum + ".cached";
		}
		
	}
}